package cxm.com.util;

import java.io.File;

import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.preference.PreferenceManager;

public class MyDownloader {
	Context context = null;
	private SharedPreferences prefs = null;
	private DownloadManager dm = null;
	private String fileToSave = null;
	private boolean isEnableNotify = true;
	Uri resource = null;
	DownloadManager.Request request = null;
	
	public MyDownloader(Context context, String uri, String fileToSave) {
		this.context = context;
		this.fileToSave = fileToSave;
		
		// instance DownloadManager for update apk
		this.prefs = PreferenceManager.getDefaultSharedPreferences(context);
        this.dm = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
        this.resource = Uri.parse(uri);

        // construct request
		this.constructRequest();
	}
	
	public void startDownload() {
		if (!StorageHelper.isExternalStorageWritable()) {
			MyLog.Log(MyLog.Level.Error, "External storage invaliable");
			return;
		}
		int status = this.queryDownloadStatus();
		// auto retry after failed
		if (DownloadManager.STATUS_FAILED == status) {
			MyLog.Log(MyLog.Level.Info, "Auto retry because of last download failed");
			this.clear();
			// check file exist to delete
			File file = StorageHelper.getFile(StorageHelper.StorageType.StorageExtrenal,
					this.fileToSave);
			if (file.exists())
				if (!file.delete())
					MyLog.Log(MyLog.Level.Error, "Cannot delete file " + file.toString());
			this.constructRequest();
			// put key to save
			if (!prefs.contains(fileToSave)) {
				prefs.edit().putLong(fileToSave, dm.enqueue(request)).commit();
				long id = this.prefs.getLong(this.fileToSave, 0);
				MyLog.Log(MyLog.Level.Debug, "Svae download id to Preference: " + id);
			}
			
		}
	}
	
	private void constructRequest() {
		// reconstruct request
		request = new DownloadManager.Request(resource);
		request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
		request.setAllowedOverRoaming(false);
		request.setTitle("Download Sample");
		request.setDescription("apk");
		request.setDestinationUri(Uri.fromFile(StorageHelper.getFile(
				StorageHelper.StorageType.StorageExtrenal, fileToSave)));
		this.enableNotification(this.isEnableNotify);
	}
	
	public void enableNotification(boolean enable) {
		if (enable)
			this.request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
		else
			this.request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
		this.isEnableNotify = enable;
	}
	
	public File getDownloadFile() {
		return StorageHelper.getFile(
				StorageHelper.StorageType.StorageExtrenal, this.fileToSave);
	}
	
	// -1 for downloading not start
	public int queryDownloadStatus() {
		// check file exist
		if (!StorageHelper.isExternalStorageWritable()) {
			MyLog.Log(MyLog.Level.Error, "External storage invaliable");
			return -1;
		}
		// clean prefs if necessary
		File file = StorageHelper.getFile(StorageHelper.StorageType.StorageExtrenal,
				this.fileToSave);
		if (!file.exists()) {
			MyLog.Log(MyLog.Level.Warning, "File not exist, clear prefs");
			this.clear();
			return DownloadManager.STATUS_FAILED;
		}

        DownloadManager.Query query = new DownloadManager.Query();
        long id = this.prefs.getLong(this.fileToSave, 0);
        query.setFilterById(id);
        Cursor c = dm.query(query);
        if (c.moveToFirst())
        	return c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
        else
        	return DownloadManager.STATUS_FAILED;
    }
	
	public void clear() {
		MyLog.Log(MyLog.Level.Debug, "Clean downloaded file: " + this.fileToSave);
		long id = this.prefs.getLong(this.fileToSave, 0);
		dm.remove(id);
		prefs.edit().remove(this.fileToSave).commit();
	}
}
